package com.zmn.oms.zmn.business.impl.part;

import com.google.common.collect.Lists;
import com.zmn.base.oms.common.model.es.orderpart.EsOrderPart;
import com.zmn.brs.common.enums.EventEnum;
import com.zmn.brs.common.enums.RecordFieldEnum;
import com.zmn.brs.starter.annotation.RecordField;
import com.zmn.brs.starter.annotation.StaffOperateRecord;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.mcc.dubbo.interfaces.role.RoleListRemoteService;
import com.zmn.oms.business.impl.base.AbstractListEsQueryServiceImpl;
import com.zmn.oms.business.interfaces.es.OrderPartEsBService;
import com.zmn.oms.business.interfaces.part.OrderPartListBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.model.dto.part.PartSumDTO;
import com.zmn.oms.model.entity.part.OrderPartEsQuery;
import com.zmn.oms.model.vo.part.ZsOrderPartStatVO;
import com.zmn.oms.model.vo.part.ZsOrderPartVO;
import com.zmn.oms.zmn.business.interfaces.part.ZsOrderPartQueryBService;
import org.apache.dubbo.config.annotation.Reference;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 类描述：工单配件
 *
 * @author lujia
 * @date 2018/12/28 20:15
 */
@Service
public class ZsOrderPartQueryBServiceImpl extends AbstractListEsQueryServiceImpl implements ZsOrderPartQueryBService {

    @Autowired
    OrderPartEsBService orderPartEsBService;
    @Autowired
    private OrderPartListBService orderPartListBService;

    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    private RoleListRemoteService roleListRemoteService;

    @StaffOperateRecord(staffId = "{{#query.staffId}}",
            event = EventEnum.WORK_ORDER_QUERY,
            mapping = {
                    @RecordField(field = RecordFieldEnum.STAFF_IP, value = "{{#query.ip}}"),
                    @RecordField(field = RecordFieldEnum.PLAT, value = "10")
            })
    @Override
    public List<ZsOrderPartVO> listPageOrderPartByQuery(OrderPartEsQuery query) {
        return baseListPageOrderPartByQuery(query);
    }

    @StaffOperateRecord(staffId = "{{#query.staffId}}",
            event = EventEnum.WORK_ORDER_EXPORT,
            mapping = {
                    @RecordField(field = RecordFieldEnum.STAFF_IP, value = "{{#query.ip}}"),
                    @RecordField(field = RecordFieldEnum.PLAT, value = "10")
            })
    @Override
    public List<ZsOrderPartVO> exportListOrderPartByQuery(OrderPartEsQuery query) {
        return baseListPageOrderPartByQuery(query);
    }

    private List<ZsOrderPartVO> baseListPageOrderPartByQuery(OrderPartEsQuery query) {

        // 处理查询条件
        this.processQuery(query);

        List<EsOrderPart> esOrderPartList = orderPartListBService.listPageOrderPartByQuery(query);
        List<ZsOrderPartVO> orderPartVOList = Lists.newArrayListWithCapacity(query.getPageSize());
        esOrderPartList.forEach(orderPart -> {
            ZsOrderPartVO orderPartVO = new ZsOrderPartVO();
            BeanMapper.copy(orderPart, orderPartVO);
            orderPartVO.setPartTypeName(OrderConsts.getPartTypeName(orderPart.getPartType()));
            orderPartVO.setReimburseStatusName(OrderConsts.getOrderPartReimburseStatusName(orderPart.getReimburseStatus()));
            orderPartVOList.add(orderPartVO);
        });
        return orderPartVOList;
    }

    @Override
    public List<ZsOrderPartStatVO> listOrderPartStatByQuery(OrderPartEsQuery query) {

        NativeSearchQuery searchQuery = (NativeSearchQuery) super.builderSearchQuery(query);
        searchQuery.setPageable(PageRequest.of(0, 1));

        BoolQueryBuilder queryBuilder = (BoolQueryBuilder) searchQuery.getQuery();
        queryBuilder.filter().add(QueryBuilders.existsQuery("accountTime"));

        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("companyName").field("companyName").size(10000);
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("inSourcingAmount").field("inSourcingPartAmount"));
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("outSourcingAmount").field("outSourcingPartAmount"));
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("deliverAmount").field("deliverAmount"));
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("partReimburseAmount").field("partReimburseAmount"));
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("partAmount").field("partAmount"));
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("totalAmount").field("totalAmount"));

        searchQuery.addAggregation(termsAggregationBuilder);

        Aggregations aggregations = orderPartEsBService.getAggregationsByQuery(searchQuery);
        ParsedStringTerms companyTerms = aggregations.get("companyName");
        List<? extends Terms.Bucket> buckets = companyTerms.getBuckets();

        List<ZsOrderPartStatVO> list = Lists.newArrayList();
        if (buckets != null && !buckets.isEmpty()) {
            buckets.forEach(bucket -> {
                long docCount = bucket.getDocCount();

                Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();
                ParsedSum inSourcingAmount = (ParsedSum) stringAggregationMap.get("inSourcingAmount");
                ParsedSum outSourcingAmount = (ParsedSum) stringAggregationMap.get("outSourcingAmount");
                ParsedSum deliverAmount = (ParsedSum) stringAggregationMap.get("deliverAmount");
                ParsedSum partReimburseAmount = (ParsedSum) stringAggregationMap.get("partReimburseAmount");
                ParsedSum partAmount = (ParsedSum) stringAggregationMap.get("partAmount");
                ParsedSum totalAmount = (ParsedSum) stringAggregationMap.get("totalAmount");

                ZsOrderPartStatVO orderPartStatVO = new ZsOrderPartStatVO();
                orderPartStatVO.setCompanyName(bucket.getKeyAsString());

                orderPartStatVO.setInSourcingAmount((int) inSourcingAmount.getValue());
                orderPartStatVO.setOutSourcingAmount((int) outSourcingAmount.getValue());
                orderPartStatVO.setDeliverAmount((int) deliverAmount.getValue());
                orderPartStatVO.setReimburseAmount((int) partReimburseAmount.getValue());

                // 配件单价 已算账的配件总额/已算账的订单数
                if (partAmount.getValue() != 0 && docCount != 0) {
                    double price = MathUtil.div((int) partAmount.getValue(), NumberUtil.toInteger(docCount));
                    orderPartStatVO.setPartPrice(price);
                } else {
                    orderPartStatVO.setPartPrice(null);
                }

                // 配件单价 已算账的配件总额/已算账的订单数
                if (partAmount.getValue() != 0 && totalAmount.getValue() != 0) {
                    double scale = MathUtil.div(partAmount.getValue(), totalAmount.getValue(), 2);
                    orderPartStatVO.setScale(scale);
                } else {
                    orderPartStatVO.setPartPrice(null);
                }
                list.add(orderPartStatVO);
            });
        }
        return list;
    }

    @Override
    public ZsOrderPartVO totalOrderPartByQuery(OrderPartEsQuery query) {
        PartSumDTO partSumVO = orderPartListBService.totalOrderPartByQuery(query);
        ZsOrderPartVO partVO = new ZsOrderPartVO();
        partVO.setAmount(partSumVO.getAmount());
//        partVO.setNumber(partSumVO.getNumber());
        return partVO;
    }

    /**
     * 查询条件处理
     *
     * @param query
     */
    private void processQuery(OrderPartEsQuery query) {

//        // 处理回溯天数
//        if (Objects.equals(query.getPermit(), GlobalConsts.YES)) {
//            ResponseDTO<List<RoleDRO>> listResponseDTO = roleListRemoteService.listByIds(query.getRoleIds());
//            List<RoleDRO> roleDROList = listResponseDTO.getData();
//            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(roleDROList)) {
//                RoleDRO roleDRO = roleDROList.stream().max((item1, item2) -> {
//                    if (Objects.isNull(item1.getDayLimit())) {
//                        return -1;
//                    }
//                    if (Objects.isNull(item2.getDayLimit())) {
//                        return 1;
//                    }
//                    if (item1.getDayLimit() > item2.getDayLimit()) {
//                        return 1;
//                    } else {
//                        return -1;
//                    }
//                }).get();
//
//                if (Objects.nonNull(roleDRO.getDayLimit())) {
//                    Date minDate = DateUtil.addDays(new Date(), -1 * roleDRO.getDayLimit());
//                    query.set(String.format("%s,", DateUtil.dateFormatToString(minDate, DateUtil.FORMAT_DEFAULT)));
//                }
//            }
//        }

    }
}
